package com.xiaoshu.test.rpc.netty.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

public class NettyRpcServiceMain {

	public static void main(String[] args) {
		int port;

		if (args.length > 0) {
			port = Integer.parseInt(args[0]);
		} else {
			port = 8080;
		}
		System.out.println("start up The Netty Server ...");
		new NettyRpcServiceMain(port).start();
	}

	private int port;

	public NettyRpcServiceMain(int port) {
		super();
		this.port = port;
	}

	public void start() {
		EventLoopGroup bossGroup = new NioEventLoopGroup();
		EventLoopGroup workerGroup = new NioEventLoopGroup();

		try {
			ServerBootstrap serverBootStap = new ServerBootstrap();
			serverBootStap
					.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.localAddress(port)
					.childHandler(new ChannelInitializer<Channel>() {

						@Override
						protected void initChannel(Channel ch) throws Exception {
							ChannelPipeline pipeLine = ch.pipeline();

							pipeLine.addLast(new LengthFieldBasedFrameDecoder(
									Integer.MAX_VALUE, 0, 4, 0, 4));
							pipeLine.addLast(new LengthFieldPrepender(4));
							pipeLine.addLast("encoder", new ObjectEncoder());
							pipeLine.addLast("decoder", new ObjectDecoder(Integer.MAX_VALUE,
											ClassResolvers.cacheDisabled(null)));
							pipeLine.addLast(new InvokerHandler());

						}
					}).option(ChannelOption.SO_BACKLOG, 128)
					.childOption(ChannelOption.SO_KEEPALIVE, true);

			ChannelFuture future = serverBootStap.bind().sync();
			System.out.println("Server start listen at " + port);
			future.channel().closeFuture().sync();
		} catch (Exception e) {

			e.printStackTrace();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}

	}
}
